package com.swak.utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import com.swak.codec.Encodes;

/**
 * image 操作
 * 
 * @author 618lf
 */
public class ImageUtils {

	/**
	 * 转为 base64;
	 * 
	 * @param image
	 * @return
	 */
	public static String toBase64(File image) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			BufferedImage bufferedImage = ImageIO.read(image);
			BufferedImage transformImage = ImageUtils.transform2PNG(bufferedImage);
			ImageIO.write(transformImage, "png", out);
			return Encodes.encodeBase64(out.toByteArray());
		} catch (Exception e) {
			return StringUtils.EMPTY;
		} finally {
			IOUtils.closeQuietly(out);
		}
	}
	
	/**
	 * 转为 base64;
	 * 
	 * @param image
	 * @return
	 */
	public static String toBase64(InputStream image) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			BufferedImage bufferedImage = ImageIO.read(image);
			BufferedImage transformImage = ImageUtils.transform2PNG(bufferedImage);
			ImageIO.write(transformImage, "png", out);
			return Encodes.encodeBase64(out.toByteArray());
		} catch (Exception e) {
			return StringUtils.EMPTY;
		} finally {
			IOUtils.closeQuietly(out);
		}
	}

	/**
	 * 转为 base64;
	 * 
	 * @param image
	 * @return
	 */
	public static String toBase64(BufferedImage image) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			ImageIO.write(image, "png", out);
			return Encodes.encodeBase64(out.toByteArray());
		} catch (Exception e) {
			return null;
		} finally {
			IOUtils.closeQuietly(out);
		}
	}

	/**
	 * 转换格式
	 * 
	 * @param image
	 * @return
	 */
	public static BufferedImage transform2PNG(BufferedImage image) {
		BufferedImage newBufferedImage = new BufferedImage(image.getWidth(), image.getHeight(),
				BufferedImage.TYPE_INT_RGB);
		newBufferedImage.createGraphics().drawImage(image, 0, 0, Color.white, null);
		return newBufferedImage;
	}

	/**
	 * 生成圆角图片
	 *
	 * @param image        原始图片
	 * @param cornerRadius 圆角的弧度
	 * @return 返回圆角图
	 */
	public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
		int w = image.getWidth();
		int h = image.getHeight();
		BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

		Graphics2D g2 = output.createGraphics();

		// This is what we want, but it only does hard-clipping, i.e. aliasing
		// g2.setClip(new RoundRectangle2D ...)

		// so instead fake soft-clipping by first drawing the desired clip shape
		// in fully opaque white with antialiasing enabled...
		g2.setComposite(AlphaComposite.Src);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setColor(Color.WHITE);
		g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius));

		// ... then compositing the image on top,
		// using the white shape from above as alpha source
		g2.setComposite(AlphaComposite.SrcAtop);
		g2.drawImage(image, 0, 0, null);

		g2.dispose();

		return output;
	}

	/**
	 * 两张图片绘制在一起， 制在正中间
	 *
	 * @param background 背景图
	 * @param image      需要绘制的图
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage drawImage(BufferedImage background, BufferedImage image) throws IOException {
		int bgW = background.getWidth();
		int bgH = background.getHeight();
		int imgW = image.getWidth();
		int imgH = image.getHeight();

		// 图片的大小不应大于原图
		if (imgW > bgW) {
			imgW = bgW;
		}

		if (imgH > bgH) {
			imgH = bgH;
		}

		// 绘制图片
		int imgX = (bgW - imgW) >> 1;
		int imgY = (bgH - imgH) >> 1;
		return drawImage(background, image, imgW, imgH, imgX, imgY);
	}

	/**
	 * 两张图片绘制在一起
	 *
	 * @param background 背景图
	 * @param image      需要绘制的图
	 * @param imgW       图片图宽
	 * @param imgH       图片图高
	 * @param imgX       图片X坐标
	 * @param imgY       图片Y坐标
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage drawImage(BufferedImage background, BufferedImage image, int imgW, int imgH, int imgX,
			int imgY) throws IOException {
		int bgW = background.getWidth();
		int bgH = background.getHeight();

		// 图片的大小不应大于原图
		if (imgW > bgW) {
			imgW = bgW;
		}

		if (imgH > bgH) {
			imgH = bgH;
		}

		// 绘制图片 -- 透明度， 避免看不到背景
		Graphics2D g2d = background.createGraphics();
		if (imgW == bgW) {
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.85f));
		}
		g2d.drawImage(image, imgX, imgY, imgW, imgH, null);
		if (imgW == bgW) {
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
		}
		g2d.dispose();
		background.flush();
		return background;
	}

	/**
	 * 绘制背景图
	 *
	 * @param background 背景图
	 * @param bgW        背景图宽
	 * @param bgH        背景图高
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage drawImage(BufferedImage background, int bgW, int bgH) throws IOException {

		// 获取背景图
		BufferedImage bg = background;
		if (bg.getWidth() != bgW || bg.getHeight() != bgH) { // 需要缩放
			BufferedImage temp = new BufferedImage(bgW, bgH, BufferedImage.TYPE_INT_ARGB);
			temp.getGraphics().drawImage(bg.getScaledInstance(bgW, bgH, Image.SCALE_SMOOTH), 0, 0, null);
			bg = temp;
		}
		bg.flush();
		return bg;
	}
}